<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /*
    已经将对象改成响应式的了，但是如果直接给对象赋值，
    赋值为另一个对象，那么就不是响应式的了？？？？
    */

  function defineReactive(target, key, value, enumerable) {
    if(typeof value === 'object' && value != null && !Array.isArray(value)) {
      reactify(value) ;
    }
    Object.defineProperty(target, key, {
      configurable: true,
      enumerable: !!enumerable,
      get() {
        console.log('读取o的'+key+'属性');
        return value
      },
      set(newVal) {
        console.log('设置o的'+key+'属性为：'+newVal);
        value = newVal
      }
    })
   }

   function reactify(o) {
    let keys = Object.keys(o)
    for(let i=0;i<keys.length;i++) {
      let key = keys[i];
      let value = o[key]
     if(Array.isArray(value)) {
      value.__proto__ = array_methods; // 数组的响应式
      for(let j=0;j<value.length;j++) {
        reactify(value[j]);
      }
     } else {
       defineReactive(o, key, value, true)
    }
  }
   }

   let data = {
     name: 'zs',
     age: 30,
     course: [
       {name: '语文'},
       {name: '数学'},
       {name: '英语'}
     ],
     user: {
       userInfo: {
         name: 'ls',
         age: 99
       }
     }
   }

    let ARRAY_METHOD = [
      "push",
      "pop",
      "shift", 
      "unshift", 
      "sort", 
      "splice"
    ]
    let array_methods = Object.create(Array.prototype);
    ARRAY_METHOD.forEach(method => {
      array_methods[method] = function() {
        console.log('调用的是拦截的'+method+'方法');
        /*
        将数据进行响应式化，数据为arguments
        */
        for(let i=0;i<arguments.length;i++) {
          reactify(arguments[i])
        }

        let res = Array.prototype[method].apply(this, arguments)
        return res;
      }
    })

    reactify(data)
  </script>
</body>
</html>